package com.tql.mall.rabbit.service;

import com.alibaba.fastjson.JSON;
import com.tql.mall.rabbit.constant.MqConstant;
import com.tql.mall.rabbit.model.MallCorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @Author: tyk
 * @Date: 2023/5/18 20:33
 * @Description: 消息发送服务：通用消息发送模板
 */
@Service
public class RabbitService {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 发送普通消息
     *
     * @param exchange   交换机
     * @param routingKey 路由
     * @param msg        消息
     */
    public boolean sendMsg(String exchange, String routingKey, Object msg) {
        // 消息ID
        String id = UUID.randomUUID().toString().replaceAll("-", "");
        // 封装消息
        MallCorrelationData data = new MallCorrelationData(id, msg, exchange, routingKey);
        // 消息缓存到redis
        redisTemplate.opsForValue().set(id, JSON.toJSONString(data), 10L, TimeUnit.MINUTES);
        // 发送消息
        rabbitTemplate.convertAndSend(exchange, routingKey, msg, data);
        return true;
    }

    /**
     * 发送延迟消息
     *
     * @param exchange   交换机
     * @param routingKey 路由
     * @param msg        消息
     * @param delayTime  延迟时间，单位：毫秒
     */
    public Boolean sendDelayMsg(String exchange, String routingKey, Object msg, int delayTime) {
        //  消息ID
        String id = UUID.randomUUID().toString().replaceAll("-", "");
        //  封装消息
        MallCorrelationData data = new MallCorrelationData(
                id, msg, exchange, routingKey, MqConstant.DEFAULT_RETRY_COUNT, true, delayTime
        );
        //  消息缓存到Redis
        this.redisTemplate.opsForValue().set(id, JSON.toJSONString(data), MqConstant.MSG_CACHE_TIME, TimeUnit.MINUTES);
        //  发送消息
        this.rabbitTemplate.convertAndSend(
                exchange,
                routingKey,
                msg,
                message -> {        //  设置延迟时间
                    message.getMessageProperties().setDelay(delayTime);
                    return message;
                },
                data
        );
        return true;
    }
}
